import {
  Module,
  NestModule,
  MiddlewareConsumer,
  RequestMethod,
} from '@nestjs/common';
// import * as path from 'path';
import { TypeOrmModule } from '@nestjs/typeorm';
import { RedisModule } from 'nestjs-redis';
//全局配置
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ExampleMiddleware } from 'src/middleware/example/example.middleware';
import { ScheduleModule } from '@nestjs/schedule';
import { UploadModule } from './module/upload/upload.module';
import { UserModule } from './module/user/user.module';
import { AccountModule } from './module/account/account.module';

import { AuthModule } from './component/auth/auth.module';
import { BackstageModule } from './module/backstage/backstage.module';

// 引入使用
import * as dotenv from 'dotenv';
const envFilePath = `.env.${process.env.NODE_ENV || `development`}`;

/**
 * 加载配置文件
 */
import FileConfig from './config/file';
import configuration from './config/index';

import * as Joi from '@hapi/joi';
import * as path from 'path';
/**
 * 全局模块引入
 */
import { ComponentModule } from './component/component.module';
import { TagModule } from './module/tag/tag.module';
import { EssayModule } from './module/essay/essay.module';
import { DrawModule } from './module/draw/draw.module';

import { StatusMonitorModule } from 'nest-status-monitor';
import statusMonitorConfig from './statusMonitor';
// import { RMQModule } from 'nestjs-rmq';
import { DatabaseModule } from './module/database/database.module';
import { ExcelModule } from './module/excel/excel.module';
import { TasksService } from './schedule/tasks.service';
import { TasksModule } from './schedule/tasks.module';


@Module({
  imports: [
    StatusMonitorModule.setUp(statusMonitorConfig),
    //1.配置config目录
    ConfigModule.forRoot({
      // 加载我们的邮件配置
      cache: true,
      envFilePath,
      load: [
        () =>
          dotenv.config({
            path: '.env',
          }),
        configuration,
        FileConfig,
      ],
      ignoreEnvFile: false,
      //忽略配置文件，为true则仅读取操作系统环境变量，常用于生产环境
      isGlobal: true,
      //配置为全局可见，否则需要在每个模块中单独导入ConfigModule
      validationSchema: Joi.object({
        ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
      }),
    }),
    //2.读取配置，这里读取的是数据库配置
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => {
        return {
          entities: [path.resolve(__dirname, '**/**.entity{.ts,.js}')],
          ...config.get('db.mysql'),
        };
      },
    }),
    ScheduleModule.forRoot(),
    RedisModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => {
        return {
          ...config.get('redis'),
        };
      },
    }),
    // RMQModule.forRootAsync({
    //   imports: [ConfigModule],
    //   inject: [ConfigService],
    //   useFactory: (config: ConfigService) => {
    //     return {
    //         exchangeName:config.get('rabbitmq.exchangeName'),
    //         connections: [
    //           {
    //             login: config.get('rabbitmq.username'),
    //             password: config.get('rabbitmq.password'),
    //             host: config.get('rabbitmq.host'),
    //             vhost :config.get('rabbitmq.vhost'),
    //           },
    //         ],
    //         isExchangeDurable: true,
    //         isQueueDurable: true,
    //         queueName: config.get('rabbitmq.queueName'),
    //     }
    //   }
    // }),
    ComponentModule,
    AuthModule,
    UploadModule,
    UserModule,
    AccountModule,
    BackstageModule,
    TagModule,
    EssayModule,
    DrawModule,
    DatabaseModule,
    ExcelModule,
    TasksModule
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(ExampleMiddleware)
      .forRoutes({ path: 'cats/*', method: RequestMethod.GET });
  }
}
